<script setup lang="ts">
import { ElForm } from 'element-plus'
import { ObjectUtil } from '@utils/object-util'
import { Pages } from '@typings/pages'
import YkDatePicker from '@yk/components/date-picker/YkDatePicker.vue'
import YkTableColumn from '@yk/components/table-column/YkTableColumn.vue'
import YkPagination from '@yk/components/pagination/YkPagination.vue'
import { Download } from '@element-plus/icons-vue'
import * as echarts from 'echarts'
import { ECharts } from 'echarts'
import { EChartsUtil, getBarsStyle } from '@utils/echarts'
import AlarmAnalysis from '@views/alarm/components/AlarmAnalysis.vue'
import { alarmBecomeSilentAPI, getAlarmListByPageAPI, getStatisticalAlarmDataByDayToDeviceAPI } from '@/api/alarm'
import { AlarmHistoryDTO } from '@/api/entity/alarm'
import { AlarmUtil, MountedCheck } from '@/utils'
import { DeviceDTO } from '@/api/entity/device'
import YkEmptyBox from '@yk/components/empty-box/YkEmptyBox.vue'
import { EmptyEnum, EmptyState } from '@yk/components/empty-box/type'
import { DeviceRoleUtil } from '@/dataset/device-role'
import { TabBarUtil } from '@/layout/components/tab-bar'

defineOptions({ name: 'DeviceAlarmRecord' })
const props = defineProps<{
  device: DeviceDTO
}>()

const mc = new MountedCheck()
onMounted(() => {
  DeviceRoleUtil.updateRole()
  initDataLine()
  searchHandle()
  mc.end()
})

onActivated(() => {
  if (mc.isMounted()) return
  DeviceRoleUtil.updateRole()
})

// region TODO 查询
const searchParams = reactive({
  // 结束时间
  endTime: '',
  // 开始时间
  startTime: '',
  deviceId: ''
})

function searchHandle () {
  pages.pageNum = 1
  searchParams.deviceId = props.device.id
  exportParams.value = ObjectUtil.copy(searchParams)
  getTableData()
  getDataLine()
}
// endregion

// region TODO 切换视图
const viewCheck = shallowRef<'chart' | 'table'>('chart')
function setViewActive (param: typeof viewCheck.value) {
  viewCheck.value = param
}
// endregion

// region TODO 数据图
const dataChart = shallowRef<ECharts>()
const dataChartRef = shallowRef<HTMLDivElement>()
const dataChartState = ref<EmptyState>(EmptyEnum.NONE)
function initDataLine () {
  dataChart.value = echarts.init(dataChartRef.value)
  EChartsUtil.addResizeListener(dataChart.value)
  const option = getBarsStyle({
    names: ['报警中', '已恢复'], unit: '次', colors: ['#FC5555', '#47B347']
  }).setGrid({ top: 80 })
    .setYAxis({ minInterval: 1 })
    .setLegend({ show: false })
    .setSeries([{
      stack: 'alarm'
    }, {
      stack: 'alarm',
      barMaxWidth: 15,
      itemStyle: {
        borderRadius: [5, 5, 0, 0]
      }
    }]).getResult()
  option.title = {
    text: '报警次数统计',
    left: 'center'
  }
  dataChart.value.setOption(option)
}

function getDataLine () {
  dataChartState.value = EmptyEnum.LOADING
  getStatisticalAlarmDataByDayToDeviceAPI({
    ...searchParams,
    deviceId: props.device.id
  }).then((res) => {
    res.result().then((rdata) => {
      const data = rdata.data || []
      const xAxis = []
      const series = [[], []]
      if (data.length) {
        dataChartState.value = EmptyEnum.SUCCESS
        for (let i = 0, len = data.length; i < len; i++) {
          const item = data[i]
          xAxis.push(item.time)
          series[0].push(item.alarmCount)
          series[1].push(item.recoverCount)
          dataChart.value.setOption({
            xAxis: [{ data: xAxis }],
            series: [
              { data: series[0] },
              { data: series[1] }
            ]
          })
        }
      } else {
        dataChartState.value = { type: EmptyEnum.EMPTY_TIP, description: '这段时间设备很健康，无报警信息' }
      }
    }).catch(() => {
      dataChartState.value = EmptyEnum.EMPTY
    })
  }).catch(() => {
    dataChartState.value = EmptyEnum.EMPTY
  })
}

onBeforeUnmount(() => {
  EChartsUtil.removeResizeListener(dataChart.value)
})
// endregion

// region TODO 表格数据
const pages = reactive(new Pages())
const tableData = shallowRef<AlarmHistoryDTO[]>([])
const tableDataState = ref<EmptyState>(EmptyEnum.NONE)
function getTableData () {
  tableDataState.value = EmptyEnum.LOADING
  getAlarmListByPageAPI({
    ...pages.getParams(),
    param: searchParams
  }).then((res) => {
    res.result().then((rdata) => {
      tableData.value = rdata.records || []
      pages.total = rdata.total
    })
  }).finally(() => {
    tableDataState.value = EmptyEnum.SUCCESS
  })
}
// endregion

// region TODO 消音
function alarmErasure (item: AlarmHistoryDTO) {
  const loading = ElLoading.service()
  alarmBecomeSilentAPI({ id: item.id, status: true }).then((res) => {
    res.result().then(() => {
      ElMessage.success('报警已消音')
      item.status = true
    })
  }).finally(loading.close)
}
// endregion

// region TODO 导出
const exportParams = shallowRef<typeof searchParams>()
// endregion

// region TODO 报警分析
// 对话框
const alarmAnalysisModel = ref(false)
// 报警分析 - 报警数据
const alarmAnalysisData = ref<AlarmHistoryDTO>()
function showAlarmAnalysis (data: AlarmHistoryDTO) {
  alarmAnalysisData.value = data
  alarmAnalysisModel.value = true
}
function closeAlarmAnalysis () {
  alarmAnalysisModel.value = false
}
// endregion

// region TODO 跳转
// 报警规则
function toAlarmRule (id: string) {
  TabBarUtil.value.reopen({ name: 'AlarmRule', params: { id } })
}
// endregion

// region TODO 监听设备发生变化
watch(() => props.device, (nv, ov) => {
  if (props.device && nv.id !== ov?.id) {
    searchHandle()
  }
})
// endregion
</script>

<template>
  <div class="wh-100 c_card-white">
    <div class="c_card_header">
      <div class="c_card-title">报警记录</div>
      <div class="c_header_right">
        <el-link href="/#/alarm/alarm-report" type="primary">
          <span class="color-primary">查看全部报警</span>
        </el-link>
      </div>
    </div>
    <!--搜索表单-->
    <el-form inline class="c_form-search">
      <el-form-item>
        <yk-date-picker
          v-model:start="searchParams.startTime" v-model:end="searchParams.endTime" type="daterange"
          value-format="YYYY-MM-DD HH:mm:ss"
          :days="30"
          :default-date="6"
        />
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="searchHandle">查询</el-button>
      </el-form-item>
    </el-form>
    <div style="height: calc(100% - 80px);">
      <!--功能栏-->
      <div class="position-relative">
        <div class="control-strip position-absolute" style="z-index: 20">
          <div class="control-strip__item" :class="{ 'is-active' : viewCheck === 'chart' }" @click="setViewActive('chart')">
            <ic-data-line class="icon" />
            <span>数据图</span>
          </div>
          <div class="control-strip__item" :class="{ 'is-active' : viewCheck === 'table' }" @click="setViewActive('table')">
            <ic-data-table class="icon" />
            <span>表格</span>
          </div>
        </div>
      </div>
      <!--数据图-->
      <yk-empty-box v-show="viewCheck === 'chart'" :state="dataChartState" class="h-100">
        <div ref="dataChartRef" class="h-100" />
      </yk-empty-box>
      <!--表格-->
      <div v-if="viewCheck === 'table'" v-ref-height class="h-100">
        <yk-empty-box :state="tableDataState" class="h-100">
          <template #default>
            <div class="text-right">
              <export-file url="/alarmHistory/export" :params="exportParams">
                <el-button class="c_btn--export" :icon="Download as any">导出</el-button>
              </export-file>
            </div>
            <!--表格-->
            <el-table
              class="c_table-page w-100 mt-16" stripe
              :data="tableData"
              max-height="calc(var(--ref-height) - 93px)"
            >
              <el-table-column label="#" type="index" fixed />
              <yk-table-column label="变量" prop="variableName" />
              <yk-table-column label="报警值" prop="alarmValue" />
              <yk-table-column label="触发条件">
                <template #default="scope">{{ AlarmUtil.formatCondition(scope.row.condition) }}</template>
              </yk-table-column>
              <yk-table-column label="报警时间" prop="alarmAt" />
              <el-table-column label="状态">
                <template #default="scope">
                  <el-tag v-if="scope.row.alarmState" type="danger" effect="dark" size="small">报警</el-tag>
                  <el-tag v-else type="success" effect="dark" size="small">正常</el-tag>
                </template>
              </el-table-column>
              <yk-table-column label="恢复时间" prop="recoverAt" />
              <el-table-column label="操作" width="220px">
                <template #default="scope">
                  <div class="c_table-operation">
                    <el-link type="primary" size="small" @click="showAlarmAnalysis(scope.row)">故障分析</el-link>
                    <el-link
                      v-if="DeviceRoleUtil.isAdmin(scope.row.deviceId)" type="primary" size="small"
                      @click="toAlarmRule(scope.row.alarmId)"
                    >
                      报警设置
                    </el-link>
                    <template v-if="DeviceRoleUtil.isManager(scope.row.deviceId)">
                      <el-link
                        v-if="!scope.row.status" type="danger"
                        size="small"
                        @click="alarmErasure(scope.row)"
                      >
                        消音
                      </el-link>
                      <span v-else class="ml-16 color-secondary">已消音</span>
                    </template>
                  </div>
                </template>
              </el-table-column>
            </el-table>
            <!--分页-->
            <yk-pagination class="c_table-pagination-page" :pages="pages" @handle="getTableData" />
          </template>
        </yk-empty-box>
      </div>
    </div>
    <!--报警分析-->
    <el-dialog
      v-model="alarmAnalysisModel" title="报警分析" width="800px"
      :close-on-click-modal="false" draggable :modal="false"
      @close="closeAlarmAnalysis"
    >
      <alarm-analysis :alarm="alarmAnalysisData" />
    </el-dialog>
  </div>
</template>

<style scoped lang="scss">
.control-strip {
  background-color: #F7F8FA;
  padding: 4px;
  border-radius: 2px;
  display: inline-flex;
  .control-strip__item {
    padding: 4px 16px;
    border-radius: 2px;
    color: var(--el-text-color-regular);
    @include d-flex(center);
    font-size: 14px;
    cursor: pointer;
    .icon {
      margin-right: 4px;
      font-size: 16px;
    }
    &.is-active {
      color: var(--el-color-primary);
      background-color: white;
    }
  }
}
</style>
